struct ListNode {
  int val;
  ListNode *next;
  ListNode() : val(0), next(nullptr) {}
  ListNode(int x) : val(x), next(nullptr) {}
  ListNode(int x, ListNode *next) : val(x), next(next) {}
};

class Solution {
public:
  ListNode *removeNthFromEnd(ListNode *head, int n) {
    ListNode resHead{0, head};
    ListNode *leftPtr = &resHead, *rightPtr = &resHead;
    for (int i = 0; i <= n; ++i) {
      rightPtr = rightPtr->next;
    }

    while (rightPtr != nullptr) {
      leftPtr = leftPtr->next;
      rightPtr = rightPtr->next;
    }
    ListNode *toRemove = leftPtr->next;
    leftPtr->next = toRemove->next;
    delete toRemove;
    return resHead.next;
  }
};
